﻿; (function (global) {

    'use strict';
    global.ObjectSerializer = {

        init: function () {

        },

        serialize: function (instance) {
            return JSON.stringify(instance);
        },

        deserializeAuto: function (jsonString) {
            return JSON.parse(jsonString, this.jsonReviver.bind(this));
        },

        jsonReviver: function (key, data) {
            if (key === '') {
                return this.tryRevive(data);
            }

            return data;
        },

        // faster
        deserializeRoot: function (jsonString) {
            var data = JSON.parse(jsonString);

            if (Object.prototype.toString.call(data) === '[object Array]') {
                return this.tryReviveArray(data);
            }


            return this.tryRevive(data);
        },


        canRevive: function (data) {
            var type = data._t;
            if (type && global[type] && global[type].revive) {
                return true;
            }
            return false;
        },

        tryRevive: function (data) {
            if (this.canRevive(data)) {
                return global[data._t].revive(data);
            }
            return data;
        },

        tryReviveArray: function (data) {
            if (Object.prototype.toString.call(data) === '[object Array]') {
                var arr = [];
                for (var i = 0; i < data.length; i++) {
                    arr[i] = this.tryReviveArray(data[i]);
                }
                return arr;
            }

            return this.tryRevive(data);
        },

        duplicate: function (instance) {
            return this.deserializeRoot(this.serialize(instance));
        }
    };

    global.ObjectSerializer.init();

}(this));
